package com.aly.game.exe2lua.enums;

import com.aly.game.exe2lua.builder.BaseExportBuilder;
import com.aly.game.exe2lua.builder.impl.CSVBuilder;
import com.aly.game.exe2lua.builder.impl.JSONBuilder;
import com.aly.game.exe2lua.builder.impl.LuaBuilder;
import com.aly.game.exe2lua.funcs.Props;

import java.util.function.BiConsumer;
import java.util.function.Function;

enum ExportConfigImpl implements ExportConfig {
    CSV(".csv", CSVBuilder::new, true, '{', '}'),            //
    LUA(".lua", LuaBuilder::new, false, '(', ')'),            //
    JSON(".json", JSONBuilder::new, false, '(', ')');          //

    private boolean writeBom;
    private char[] headFix;
    private String savePath;
    private boolean enable;
    private BaseExportBuilder builder;
    private String fileFix;
    private String header;

    ExportConfigImpl(String fileFix, Function<ExportConfig, BaseExportBuilder> builder, boolean writeBom, char... headFix) {
        this.fileFix = fileFix;
        this.builder = builder.apply(this);
        this.headFix = headFix;
        this.writeBom = writeBom;
    }

    public static void init(Props props) {
        for (Config configType : Config.values()) {
            for (ExportConfigImpl procType : ExportConfigImpl.values()) {
                String fullConfigName = "exports." + procType.name().toLowerCase() + "." + configType.name();
                String config = props.get(fullConfigName);
                if (config == null || config.length() == 0) {
                    // 兼容代码
                    config = fromOldConfig(props, configType, procType);
                }
                configType.func.accept(procType, config);
            }
        }
    }

    /**
     * 兼容老的配置方式
     */
    private static String fromOldConfig(Props props, Config value, ExportConfigImpl procType) {
        switch (value) {
            case enable: {
                String exportType = props.get("exportType").toLowerCase();
                boolean contains = exportType.contains(procType.name().toLowerCase());
                return Boolean.valueOf(contains).toString();
            }
            case savePath: {
                switch (procType) {
                    case CSV:
                        return props.get("exportCsvPath");
                    case LUA:
                        return props.get("exportLuaPath");
                    case JSON:
                        return props.get("exportJsonPath");
                }
            }
            break;
            case fileFix:
                if (procType == LUA) {
                    return props.get("luaFileSuffix");
                }
                break;
        }
        return "";
    }

    @Override
    public char[] getHeadFix() {
        return headFix;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    @Override
    public String getSavePath() {
        return savePath;
    }

    public void setSavePath(String savePath) {
        this.savePath = savePath == null ? "" : savePath;
    }


    @Override
    public boolean isWriteBom() {
        return writeBom;
    }

    @Override
    public BaseExportBuilder getBuilder() {
        return builder;
    }

    @Override
    public String getFileFix() {
        return fileFix;
    }

    public void setFileFix(String fileFix) {
        this.fileFix = fileFix;
    }

    @Override
    public String getFileHeader() {
        return header;
    }

    private void setHeader(String header) {
        this.header = header;
    }

    private enum Config {
        enable((procType, s) -> {
            procType.setEnable(Boolean.parseBoolean(s));
        }),
        savePath(ExportConfigImpl::setSavePath),
        fileFix(ExportConfigImpl::setFileFix),
        header(ExportConfigImpl::setHeader);

        private final BiConsumer<ExportConfigImpl, String> func;

        Config(BiConsumer<ExportConfigImpl, String> consumer) {
            this.func = consumer;
        }
    }
}
